package de.fhtrier.mp.wollmaus.util;

import java.io.IOException;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Random;

import org.newdawn.slick.Animation;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.Sound;
import org.newdawn.slick.particles.ParticleIO;
import org.newdawn.slick.particles.ParticleSystem;

public class AssetManager {
	private static AssetManager instance;
	
	// Sounds
	public static final int MUSIC_LEVEL1 = 0;
	public static final int MUSIC_LEVEL2 = 1;
	public static final int MUSIC_LEVEL3 = 2;
	public static final int MUSIC_LEVEL4 = 3;

	public static final int MUSIC_MENU = 4;

	public static final int SOUND_PLAYER_JUMP = 0;
		private static final int SOUND_PLAYER_JUMP_SOUNDS = 3;
	public static final int SOUND_PLAYER_JUMP_1 = 1;
	public static final int SOUND_PLAYER_JUMP_2 = 2;
	public static final int SOUND_PLAYER_JUMP_3 = 3;

	public static final int SOUND_NOTE_D1 = 4;
	public static final int SOUND_NOTE_D2 = 5;
	public static final int SOUND_NOTE_F1 = 6;
	public static final int SOUND_NOTE_F2 = 7;
	public static final int SOUND_NOTE_A1 = 8;
	public static final int SOUND_NOTE_A2 = 9;

	public static final int SOUND_PLAYER_FALL = 10;
		private static final int SOUND_PLAYER_FALL_SOUNDS = 4;
	public static final int SOUND_PLAYER_FALL_1 = 11;
	public static final int SOUND_PLAYER_FALL_2 = 12;
	public static final int SOUND_PLAYER_FALL_3 = 13;
	public static final int SOUND_PLAYER_FALL_4 = 14;

	// Images
	public static final int IMAGE_NOTEBAR = 0;
	public static final int IMAGE_NOTE0 = 1;
	public static final int IMAGE_NOTE1 = 2;
	public static final int IMAGE_NOTE2 = 3;
	public static final int IMAGE_NOTE3 = 4;
		static final int NOTE_ANI_PICS = 17;
		static final int NOTE_ANI_DUR = 80;

	public static final int IMAGE_NOTE0_TRANS = 5;
	public static final int IMAGE_NOTE1_TRANS = 6;
	public static final int IMAGE_NOTE2_TRANS = 7;
	public static final int IMAGE_NOTE3_TRANS = 8;

	public static final int IMAGE_INTRO_1 = 9;
	public static final int IMAGE_INTRO_2 = 10;
	public static final int IMAGE_INTRO_3 = 11;
	public static final int IMAGE_INTRO_4 = 12;

	public static final int IMAGE_MENU_MAIN = 13;
	public static final int IMAGE_MENU_CREDITS = 14;
	public static final int IMAGE_MENU_RULES = 15;
	public static final int IMAGE_MENU_WON = 16;
	public static final int IMAGE_MENU_STORY = 17;

	// Anis
	public static final int ANI_ARROW = 0;
		static final int ANI_ARROW_PICS = 42;
		static final int ANI_ARROW_DUR = 50;
	// 1-4 sind durch Notes besetzt!
	public static final int ANI_INTRO_SHADOW = 5;
		static final int ANI_INTRO_SHADOW_PICS = 32;
		static final int ANI_INTRO_SHADOW_DUR = 140;
	public static final int ANI_INTRO_POINT = 6;
		static final int ANI_INTRO_POINT_PICS = 124;
		static final int ANI_INTRO_POINT_DUR = 50;
	public static final int ANI_SPIDER = 7;
		static final int ANI_SPIDER_PICS = 263;
		static final int ANI_SPIDER_DUR = 50;
	public static final int ANI_SLEEP_SPIDER = 8;
		static final int ANI_SLEEP_SPIDER_PICS = 35;
		static final int ANI_SLEEP_SPIDER_DUR = 50;
	public static final int ANI_SLEEP_FLOCKE = 8;
		static final int ANI_SLEEP_FLOCKE_PICS = 65;
		static final int ANI_SLEEP_FLOCKE_DUR = 50;

	// Particles
	public static final int PART_WOOL = 0;
	public static final int PART_CANDLE = 1;
	public static final int PART_DUST = 2;

	private HashMap<Integer, Sound> musicMap;
	private HashMap<Integer, Sound> soundMap;
	private HashMap<Integer, Image> imageMap;
	private HashMap<Integer, Animation> aniMap;
	private HashMap<Integer, ParticleSystem> particleMap;

	public AssetManager() {
		musicMap = new HashMap<Integer, Sound>();
		soundMap = new HashMap<Integer, Sound>();
		imageMap = new HashMap<Integer, Image>();
		aniMap = new HashMap<Integer, Animation>();
		particleMap = new HashMap<Integer, ParticleSystem>();

		try {
			musicMap.put(MUSIC_LEVEL1, new Sound("./Files/music/basementfloor.ogg"));
			musicMap.put(MUSIC_LEVEL2, new Sound("./Files/music/basementfloor.ogg"));
			musicMap.put(MUSIC_LEVEL3, new Sound("./Files/music/basementfloor.ogg"));
			musicMap.put(MUSIC_LEVEL4, new Sound("./Files/music/basementfloor.ogg"));

			musicMap.put(MUSIC_MENU, new Sound("./Files/music/menumusic.ogg"));

			soundMap.put(SOUND_PLAYER_JUMP_1, new Sound("./Files/sound/player/jump.ogg"));
			soundMap.put(SOUND_PLAYER_JUMP_2, new Sound("./Files/sound/player/jump2.ogg"));
			soundMap.put(SOUND_PLAYER_JUMP_3, new Sound("./Files/sound/player/jump3.ogg"));

			soundMap.put(SOUND_PLAYER_FALL_1, new Sound("./Files/sound/player/fall1.ogg"));
			soundMap.put(SOUND_PLAYER_FALL_2, new Sound("./Files/sound/player/fall2.ogg"));
			soundMap.put(SOUND_PLAYER_FALL_3, new Sound("./Files/sound/player/fall3.ogg"));
			soundMap.put(SOUND_PLAYER_FALL_4, new Sound("./Files/sound/player/fall4.ogg"));

			soundMap.put(SOUND_NOTE_D1, new Sound("./Files/sound/notes/d1.ogg"));
			soundMap.put(SOUND_NOTE_D2, new Sound("./Files/sound/notes/d2.ogg"));
			soundMap.put(SOUND_NOTE_F1, new Sound("./Files/sound/notes/f1.ogg"));
			soundMap.put(SOUND_NOTE_F2, new Sound("./Files/sound/notes/f2.ogg"));
			soundMap.put(SOUND_NOTE_A1, new Sound("./Files/sound/notes/a1.ogg"));
			soundMap.put(SOUND_NOTE_A2, new Sound("./Files/sound/notes/a2.ogg"));

			imageMap.put(IMAGE_NOTEBAR, loadImage("Files/img/items/noteBar.png"));

			imageMap.put(IMAGE_NOTE0, loadImage("Files/img/items/note0.png"));
			imageMap.put(IMAGE_NOTE1, loadImage("Files/img/items/note1.png"));
			imageMap.put(IMAGE_NOTE2, loadImage("Files/img/items/note2.png"));
			imageMap.put(IMAGE_NOTE3, loadImage("Files/img/items/note3.png"));

			imageMap.put(IMAGE_NOTE0_TRANS, loadImage("Files/img/items/note0_trans.png"));
			imageMap.put(IMAGE_NOTE1_TRANS, loadImage("Files/img/items/note1_trans.png"));
			imageMap.put(IMAGE_NOTE2_TRANS, loadImage("Files/img/items/note2_trans.png"));
			imageMap.put(IMAGE_NOTE3_TRANS, loadImage("Files/img/items/note3_trans.png"));

			imageMap.put(IMAGE_INTRO_1, loadImage("Files/img/intro/1_orgelwerkstatt.jpg"));
			imageMap.put(IMAGE_INTRO_2, loadImage("Files/img/intro/1_orgelwerkstatt.jpg"));
			imageMap.put(IMAGE_INTRO_3, loadImage("Files/img/intro/3_in_der_orgel.jpg"));
			imageMap.put(IMAGE_INTRO_4, loadImage("Files/img/intro/4_orgelpfeifen.jpg"));

			imageMap.put(IMAGE_MENU_MAIN, loadImage("Files/img/menu/main.jpg"));
			imageMap.put(IMAGE_MENU_CREDITS, loadImage("Files/img/menu/credits.jpg"));
			imageMap.put(IMAGE_MENU_RULES, loadImage("Files/img/menu/help.jpg"));
			imageMap.put(IMAGE_MENU_WON, loadImage("Files/img/menu/won.jpg"));
			imageMap.put(IMAGE_MENU_STORY, loadImage("Files/img/menu/story.jpg"));

			// Partikel
			try {
				particleMap.put(PART_WOOL, ParticleIO.loadConfiguredSystem("Files/particles/wool.xml"));
				particleMap.put(PART_CANDLE, ParticleIO.loadConfiguredSystem("Files/particles/candlelight.xml"));
				particleMap.put(PART_DUST, ParticleIO.loadConfiguredSystem("Files/particles/dust.xml"));
			}
			catch (IOException e) {
				e.printStackTrace();
			}

			// Animations
			loadAnimation("00",IMAGE_NOTE0,"Files/img/items/notes/pp/pp_",".png",NOTE_ANI_PICS,NOTE_ANI_DUR,1);
			loadAnimation("00",IMAGE_NOTE1,"Files/img/items/notes/2/halb_",".png",NOTE_ANI_PICS,NOTE_ANI_DUR,1);
			loadAnimation("00",IMAGE_NOTE2,"Files/img/items/notes/16/sechzehn_",".png",NOTE_ANI_PICS,NOTE_ANI_DUR,1);
			loadAnimation("00",IMAGE_NOTE3,"Files/img/items/notes/32/zweiunddreißig_",".png",NOTE_ANI_PICS,NOTE_ANI_DUR,1);

			loadAnimation("0000",ANI_ARROW,"Files/img/items/arrow/Pfeil",".png",ANI_ARROW_PICS,ANI_ARROW_DUR,0);
			
			loadAnimation("00",ANI_INTRO_SHADOW,"Files/img/intro/shadow_",".png",ANI_INTRO_SHADOW_PICS,ANI_INTRO_SHADOW_DUR,1);
			loadAnimation("0000",ANI_INTRO_POINT,"Files/img/intro/point_ani/Pünktchen",".png",ANI_INTRO_POINT_PICS,ANI_INTRO_POINT_DUR,0);
			loadAnimation("0000",ANI_SPIDER,"Files/entity/spider/animiertes Spinnchen",".png",ANI_SPIDER_PICS,ANI_SPIDER_DUR,0);
			loadAnimation("0000",ANI_SLEEP_FLOCKE,"Files/entity/sleep_flocke/Flocke Z",".png",ANI_SLEEP_FLOCKE_PICS,ANI_SLEEP_FLOCKE_DUR,0);
			loadAnimation("0000",ANI_SLEEP_SPIDER,"Files/entity/sleep_spider/Spinne Z",".png",ANI_SLEEP_SPIDER_PICS,ANI_SLEEP_SPIDER_DUR,0);
		}
		catch (SlickException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Lädt eine Animation in die AniMap
	 * @param decimalFormat Gibt das Zahlenformat an, wie "0000"
	 * @param indentifier Der Integer, mit dem man die Ani wieder laden kann
	 * @param amountOfPics Anzahl der Bilder der Animation
	 * @param startNumber Welche Nummer hat das erste Bild
	 */
	public void loadAnimation(String decimalFormat, int indentifier, String file, String fileEnding, int amountOfPics, int duration, int startNumber) {
		DecimalFormat df = new DecimalFormat(decimalFormat);
		Image[] con = new Image[amountOfPics];
		for (int i = 0; i < amountOfPics; ++i) {
			con[i] = loadImage(file + df.format(i + startNumber) + fileEnding);
		}
		aniMap.put(indentifier, new Animation(con, duration));
	}

	public static AssetManager getInstance() {
		if (instance == null) {
			instance = new AssetManager();
		}
		return instance;
	}

	public Sound getMusic(int i) {
		return musicMap.get(new Integer(i));
	}

	public Sound getSound(int i) {
		Random generator = new Random(System.currentTimeMillis());
		if (i == SOUND_PLAYER_JUMP) {
			int rand = generator.nextInt(SOUND_PLAYER_JUMP_SOUNDS);
			return soundMap.get(new Integer(SOUND_PLAYER_JUMP_1 + rand));
		}
		else if (i == SOUND_PLAYER_FALL) {
			int rand = generator.nextInt(SOUND_PLAYER_FALL_SOUNDS);
			return soundMap.get(new Integer(SOUND_PLAYER_FALL_1 + rand));
		}
		return soundMap.get(new Integer(i));
	}

	public Image getImage(int i) {
		Image img = imageMap.get(new Integer(i));
		if (img == null) {
			System.err.println("AssetManager tried to load unknown picture: " + i);
		}
		return img;
	}

	public Animation getAnimation(int i) {
		return aniMap.get(new Integer(i));
	}

	public ParticleSystem getParticle(int i) {
		return particleMap.get(new Integer(i));
	}
	
	public Image loadImage(String path) {
		try {
			return new Image(path);
		}
		catch (SlickException e) {
			e.printStackTrace();
		}
		return null;
	}
}
